# -*- coding: utf-8 -*-
# Hardware-Architecture Render Engine (HARU)

import os
import sys
import argparse

# Add hare folder to system path.
hare_path, _ = os.path.split(__file__)
sys.path.insert(0, hare_path)


from pylang.frontend import parse_python_to_ir
from hbcxx.backend import transfer_ir_to_simcxx
from hbcxx.project import create_simcxx_project


HARE_FORMATS = {
    'simcxx': [transfer_ir_to_simcxx, 'C++ Simulation Code']
}


def display_error(error_message: str):
    print(error_message)
    exit(-1)


def parse_args():
    # Create argument parser.
    parser = argparse.ArgumentParser(description='Hardware-Architecture Render Engine')
    # Parse the argument.
    parser.add_argument('-gscx', '--generate-simcxx', dest='generate-scx',
                        help='Generate the C++ simlation framework.')
    parser.add_argument('-juna', dest='juna',
                        help='Juna C++ library path.')

    parser.add_argument('-I', '--include', dest='include', nargs='+',
                        help='Module included path.')
    parser.add_argument('-f', '--format', dest='format',
                        help='Generated format.')
    parser.add_argument('-o', '--output', dest='output',
                        help='Output file path.')
    parser.add_argument('file', nargs='?', default='',
                        help='Python node files.')
    args = parser.parse_args()
    # Give back the arguments.
    return args.__dict__


def main():
    from pylang.config import INCLUDE_PATH
    # Parse the input file and provided parameters.
    args = parse_args()
    if args['generate-scx'] is not None and len(args['generate-scx']) > 0:
        # Check juna path.
        if args['juna'] is None or len(args['juna']) == 0:
            raise Exception('Please specify the juna C++ library path.')
        # Just need to create the project file.
        create_simcxx_project(args['generate-scx'], args['juna'])
        return
    # Check the output format and path.
    if 'format' not in args:
        display_error('Please specify the output format.')
    if 'output' not in args:
        display_error('Please specify the output file path.')
    # Append the included path to configuration.
    if 'include' in args and isinstance(args['include'], list):
        INCLUDE_PATH += args['include']
    # Based on the format, find the backend function.
    if args['format'] not in HARE_FORMATS:
        error_message = 'Unknown transfer format {}, only the ' \
                        'following formats are supported:\n'.format(args['format'])
        for backend_format in HARE_FORMATS:
            error_message += ' - {}: {}\n'.format(backend_format,
                                                  HARE_FORMATS[backend_format][1])
        display_error(error_message)
    # Convert the file into intermediate representation.
    if len(args['file']) == 0:
        display_error('Please specify the file to convert.')
    ir_module = parse_python_to_ir(args['file'])
    # Call the transfer function.
    transfer_ir, _ = HARE_FORMATS[args['format']]
    # Convert the module IR.
    transfer_ir(ir_module, args['output'], args['file'])


if __name__ == '__main__':
    main()